fix(gates): witness the ingest so truncated checkouts cannot pass silently - #178
Merged
Conversation
…ently
A shallow fetch-depth checkout whose tip is a merge commit ingests zero
history under the default merge filter, leaving every quality gate with
nothing to violate — `codelore check` printed PASS (0 files evaluated),
wrote result=pass, and exited 0. Three related gate-integrity holes are
closed as one class:
- Witness the ingest on both gate paths (`codelore check` and the
check_gates MCP tool): a real HEAD over a zero-commit store is now a hard
error (exit 3, the shallow/corrupted-repo bucket) that names fetch-depth,
never a pass. A shallow checkout that did ingest partial history is warned
about loudly, and the code_health_min degraded sentinel now witnesses
"the repository has analyzable source" by reading the HEAD tree directly
rather than counting complexity_metrics — which derives from the same
changes-commits join as the health rows and so could not fire for the
very ingest-blindness it guards. A source-less tree stays a vacuous pass.
- Disclose the [new_code] shallow-history skip as structured data on the
check_gates MCP path (a {gate, reason} entry in skipped_gates, unified
with the structural check-only skips, which gain reasons too) and make
the reason discriminate a shallow checkout (names fetch-depth) from a
genuinely young repository on both the CLI and MCP paths.
- Write .codelore-ratchet.toml atomically through the shared
write-to-temp + fsync + rename helper, so an interrupted write can no
longer leave a 0-byte file; and reject a present-but-empty ratchet file
as corrupt instead of parsing it to an all-None snapshot and silently
rebaselining the gate. No file (initialize), a well-formed empty table
(no floors configured), and a destroyed file (loud error) are now
distinct states.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three validated gate-integrity findings from the cycle-3 audit, fixed as one class — a truncated checkout must never convert configured gates into silent no-ops:
actions/checkoutdefault on PR merge refs, under default merge filtering) ingests zero commits, and every gate then passed green withresult=pass. Now: zero persisted commits + a real HEAD = hard error (exit 3, message namingfetch-depth), on bothcodelore checkand MCPcheck_gates. The witness gates on the persisted store count rather than in-memory ingest stats — a zero-commit run poisons the cache, and later cache-hits have no fresh stats; the store count is the same quantity, readable on hit and miss. A.git/shallowpreflight warns loudly. The degraded sentinel — whose old conjunction derived both sides from the same join and was structurally blind to ingest-level failure — gains an independent witness (HEAD-tree scorable-source count, computed only on the empty-health path; the commit-count case is preempted upstream, and a legitimately source-less repo stays a valid vacuous pass).check_gates'sskipped_gatesis now{gate, reason}(one unified shape — the existing structural skips gained reasons too), and the[new_code]runtime skip reports through it: an agent can finally distinguish "passed" from "did not run". Both CLI and MCP wordings discriminate a shallow checkout (naming fetch-depth) from a genuinely young repository..codelore-ratchet.toml— a committed file — was written non-atomically, and a torn 0-byte file parsed cleanly into "everything improved" + silent team-wide rebaseline. Writes now route through the sharedatomic_publish; present-but-empty content is rejected as corrupt with a restore-or-delete error. Absent / no-floors-configured / destroyed are three distinct states.Verification
checkoutput unchanged (witness guards inert on a full clone; no[new_code]configured here; no ratchet file)